
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <termios.h>

#include <math.h>

#include <sys/types.h>

#define byte unsigned char

#define HIGHBYTE(a) (a >> 16)
#define MIDBYTE(a) ((a - (HIGHBYTE(a) << 16)) >> 8)
#define LOWBYTE(a) (a - (HIGHBYTE(a) << 16) - (MIDBYTE(a) << 8))

#define DEVICE_PATH "/dev/cu.bluetooth"
//#define DEVICE_PATH "/dev/uart.bluetooth"

#define HCI_COMMAND_PKT_HDR 0x01

#define HCI_CMD_RESET			0
#define HCI_CMD_RD_LOC_SUP_FEAT		1
#define HCI_CMD_RD_LOC_VER_INFO		2
#define HCI_CMD_RD_BUFFER_SIZE		3
#define HCI_CMD_RD_BD_ADDR		4
#define HCI_CMD_RD_DEV_CLASS		5
#define HCI_CMD_RD_LOC_NAME		6

#define HCI_CMD_SET_EVENT_FILT		7
#define HCI_CMD_WRT_PG_TIMEOUT		8
#define HCI_CMD_WRT_CON_ACC_TIMEOUT	9
#define HCI_CMD_WRT_LOC_NAME		10	
#define HCI_CMD_WRT_DEV_CLASS		11	
#define HCI_CMD_RD_LINK_KEY		12	
#define HCI_CMD_RD_SCAN_ENABLE		13	
#define HCI_CMD_WRT_SCAN_ENABLE		14	
#define HCI_CMD_SET_EVENT_MASK	 	15	
#define HCI_CMD_WRT_INQ_MODE		16	

#define HCI_CMD_CONNECT			17	
#define HCI_CMD_DISCONNECT		18	
#define HCI_CMD_RD_REM_SUP_FEAT		19	
#define HCI_CMD_WRT_LINK_POLICY_SET	20	
#define HCI_CMD_REM_NAME_REQ		21	

#define HCI_CMD_WRT_BD_ADDR		22

#define HCI_CMD_RD_DEV_NAME		23

struct HCICmdInfo {
	int	cmdId;
	byte * 	commandName;
	int	commandCode1;
	int	commandCode2;
	int	size;
};

struct HCICmdInfo HCICommands[] = {
	{HCI_CMD_RESET,			(byte *) "Reset", 0x03, 0x0003, 0},
	{HCI_CMD_RD_LOC_SUP_FEAT,	(byte *) "Read Local Supported Features", 0x04, 0x0003, 0},
	{HCI_CMD_RD_LOC_VER_INFO,	(byte *) "Read Local Version Information", 0x04, 0x0001, 0},
	{HCI_CMD_RD_BUFFER_SIZE,	(byte *) "Read Buffer Size", 0x04, 0x0005, 0},
	{HCI_CMD_RD_BD_ADDR,		(byte *) "Read BD ADDR", 0x04, 0x0009, 0},
	{HCI_CMD_RD_DEV_CLASS,		(byte *) "Read Class of Device", 0x03, 0x0023, 0},
	{HCI_CMD_RD_LOC_NAME,		(byte *) "Read Local Name", 0x03, 0x0014, 0},

	{HCI_CMD_SET_EVENT_FILT,	(byte *) "Set Event Filter", 0x03, 0x0005, 1},
	{HCI_CMD_WRT_PG_TIMEOUT,	(byte *) "Write Page Timeout", 0x03, 0x0018, 2},
	{HCI_CMD_WRT_CON_ACC_TIMEOUT,	(byte *) "Write Connection Accept Timeout", 0x03, 0x0016, 2},
	{HCI_CMD_WRT_LOC_NAME,		(byte *) "Write Local Name", 0x03, 0x0013, 248},
	{HCI_CMD_WRT_DEV_CLASS,		(byte *) "Write Class of Device", 0x03, 0x0024, 3},
	{HCI_CMD_RD_LINK_KEY,		(byte *) "Read Stored Link Key ", 0x03, 0x000d, 7},
	{HCI_CMD_RD_SCAN_ENABLE,	(byte *) "Read Scan Enable", 0x03, 0x0019, 0},
	{HCI_CMD_WRT_SCAN_ENABLE,	(byte *) "Write Scan Enable", 0x03, 0x001a, 1},
	{HCI_CMD_SET_EVENT_MASK,	(byte *) "Set Event Mask", 0x03, 0x0001, 8},
	{HCI_CMD_WRT_INQ_MODE,		(byte *) "Write Inquiry Mode", 0x03, 0x0045, 1},

	{HCI_CMD_CONNECT,		(byte *) "Create Connection", 0x01, 0x0005, 13},
	{HCI_CMD_DISCONNECT,		(byte *) "Disconnect", 0x01, 0x0006, 3},
	{HCI_CMD_RD_REM_SUP_FEAT,	(byte *) "Read Remote Supported Features", 0x01, 0x001b, 2},
	{HCI_CMD_WRT_LINK_POLICY_SET,	(byte *) "Write Link Policy Settings", 0x02, 0x000d, 4},
	{HCI_CMD_REM_NAME_REQ,		(byte *) "Remote Name Request", 0x01, 0x0019, 10},

	{HCI_CMD_WRT_BD_ADDR,		(byte *) "Write BD ADDR", 0xCF, 0x000D, 6},

	{HCI_CMD_RD_DEV_NAME,		(byte *) "Get Device Name", 0x01, 0x0019, 10},
};

